package org.itboys.lock;

import org.itboys.redis.RedisClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import redis.clients.jedis.Jedis;

/**
 * redis 分布式锁 通过redis 的 setnx 实现
 * @author ChenJh
 */
public class RedisLock implements DistributedLock {

    private static Logger logger = LoggerFactory.getLogger(RedisLock.class);

    private static final String LOCK_VALUE = "1";

    private RedisClient redisClient;

    @Override
    public boolean acquire(String key) {
        Jedis jedis = null;
        try {
            jedis = redisClient.getJedis();
            Long value = jedis.setnx(key , LOCK_VALUE);
            if (value == 1L) {
                return true;
            }
        }catch (Exception e) {
            logger.error("acuqire lock error key = " + key , e);
        } finally {
            redisClient.release(jedis);
        }
        return false;
    }

    @Override
    public boolean acquire(String key, int time) {
        Jedis jedis = null;
        try {
            jedis = redisClient.getJedis();
            Long value = jedis.setnx(key , LOCK_VALUE);
            if (value == 1L) {
                jedis.expire(key , time);
                return true;
            }
        }catch (Exception e) {
            logger.error("acuqire lock error key = " + key + "time = " + time , e);
        } finally {
            redisClient.release(jedis);
        }
        return false;
    }

    @Override
    public void release(String key) {
        Jedis jedis = null;
        try {
            jedis = redisClient.getJedis();
            jedis.del(key);
        }catch (Exception e) {
            logger.error("release lock error key = " + key , e);
        } finally {
            redisClient.release(jedis);
        }
    }

    public void setRedisClient(RedisClient redisClient) {
        this.redisClient = redisClient;
    }
}
